package com.wolfking.jeesite.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wolfking.jeesite.entity.Role;
import com.wolfking.jeesite.mapper.RoleMenuRelationMapper;
import com.wolfking.jeesite.mapper.RoleOfficeRelationMapper;
import com.wolfking.jeesite.mapper.UserRoleRelationMapper;
import com.wolfking.jeesite.mybatis.BaseService;
import com.wolfking.jeesite.entity.RoleMenuRelation;
import com.wolfking.jeesite.entity.RoleOfficeRelation;
import com.wolfking.jeesite.entity.UserRoleRelation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 角色的service
 *
 * @author wolfking@赵伟伟
 * @mail zww199009@163.com
 * @创作日期 2017年5月13日 下午9:29:15
 * @copyright wolfking
 */
@Service
public class RoleService extends BaseService<Role> {

    @Autowired
    private RoleMenuRelationMapper roleMenuRelationMapper;

    @Autowired
    private RoleOfficeRelationMapper roleOfficeRelationMapper;

    @Autowired
    private UserRoleRelationMapper userRoleRelationMapper;

    @Override
    @Transactional
    public boolean save(Role role) {
        mapper.insert(role);
        List<RoleMenuRelation> roleMenuRelations = RoleMenuRelation.assemblyRelation(role);
        for (RoleMenuRelation roleMenuRelation : roleMenuRelations)
            roleMenuRelationMapper.insert(roleMenuRelation);
        List<RoleOfficeRelation> roleOfficeRelations = RoleOfficeRelation.assemblyRelation(role);
        for (RoleOfficeRelation roleOfficeRelation : roleOfficeRelations)
            roleOfficeRelationMapper.insert(roleOfficeRelation);
        return true;
    }

    @Override
    @Transactional
    public boolean updateById(Role role) {
        LambdaQueryWrapper<RoleMenuRelation> wrapperRm = new QueryWrapper<RoleMenuRelation>()
                .lambda().eq(RoleMenuRelation::getRoleId, role.getId());
        roleMenuRelationMapper.delete(wrapperRm);
        LambdaQueryWrapper<RoleOfficeRelation> wrapperRo = new QueryWrapper<RoleOfficeRelation>()
                .lambda().eq(RoleOfficeRelation::getRoleId, role.getId());
        roleOfficeRelationMapper.delete(wrapperRo);
        mapper.updateById(role);
        List<RoleMenuRelation> relations = RoleMenuRelation.assemblyRelation(role);
        for (RoleMenuRelation roleMenuRelation : relations)
            roleMenuRelationMapper.insert(roleMenuRelation);
        List<RoleOfficeRelation> roleOfficeRelations = RoleOfficeRelation.assemblyRelation(role);
        for (RoleOfficeRelation roleOfficeRelation : roleOfficeRelations)
            roleOfficeRelationMapper.insert(roleOfficeRelation);
        return true;
    }

    @Override
    @Transactional
    public List<Role> deleteById(Serializable id) {
        /*可以改成一条SQL统一删除*/
        Role role = new Role();
        role.setId((Integer) id);
        //删除角色和菜单的关联
        LambdaQueryWrapper<RoleMenuRelation> wrapperRm = new QueryWrapper<RoleMenuRelation>()
                .lambda().eq(RoleMenuRelation::getRoleId, role.getId());
        roleMenuRelationMapper.delete(wrapperRm);
        //删除角色和机构的关联
        LambdaQueryWrapper<RoleOfficeRelation> wrapperRo = new QueryWrapper<RoleOfficeRelation>()
                .lambda().eq(RoleOfficeRelation::getRoleId, role.getId());
        roleOfficeRelationMapper.delete(wrapperRo);
        //删除角色和用户的关联
        LambdaQueryWrapper<UserRoleRelation> wrapperUr = new QueryWrapper<UserRoleRelation>()
                .lambda().eq(UserRoleRelation::getRoleId, role.getId());
        userRoleRelationMapper.delete(wrapperUr);
        return super.deleteById(role);
    }

    @Override
    @Transactional(readOnly = true)
    public Role getById(Serializable id) {
        Role role = super.getById(id);
        List<RoleMenuRelation> listRM = roleMenuRelationMapper.selectList(
                new QueryWrapper<RoleMenuRelation>().lambda().eq(RoleMenuRelation::getRoleId, role.getId()));
        List<RoleOfficeRelation> listRO = roleOfficeRelationMapper.selectList(
                new QueryWrapper<RoleOfficeRelation>().lambda().eq(RoleOfficeRelation::getRoleId, role.getId()));
        String menuIds = "", officeIds = "";
        if (listRM != null) {
            menuIds = listRM.stream().map(RoleMenuRelation::getMenuId).map(String::valueOf).collect(Collectors.joining(","));
        }
        if (listRO != null) {
            officeIds = listRO.stream().map(RoleOfficeRelation::getOfficeId).map(String::valueOf).collect(Collectors.joining(","));
        }
        role.setOfficeIds(officeIds);
        role.setMenuIds(menuIds);
        return role;
    }

    @Transactional
    public void outrole(Integer roleId, Integer userId) {
        LambdaQueryWrapper<UserRoleRelation> wrapperUr = new QueryWrapper<UserRoleRelation>()
                .lambda().eq(UserRoleRelation::getRoleId, roleId).eq(UserRoleRelation::getUserId, userId);
        userRoleRelationMapper.delete(wrapperUr);
    }

    @Transactional
    public void assignrole(Integer roleId, Integer userId) {
        UserRoleRelation userRoleRelation = new UserRoleRelation(userId, roleId);
        LambdaQueryWrapper<UserRoleRelation> wrapperUr = new QueryWrapper<UserRoleRelation>()
                .lambda().eq(UserRoleRelation::getRoleId, roleId).eq(UserRoleRelation::getUserId, userId);
        userRoleRelationMapper.delete(wrapperUr);
        userRoleRelationMapper.insert(userRoleRelation);
    }


    @Transactional(readOnly = true)
    public Set<Integer> getUserRoleIds(Integer userId) {
        return userRoleRelationMapper.selectList(
                new QueryWrapper<UserRoleRelation>().lambda().eq(UserRoleRelation::getUserId, userId))
                .stream().map(UserRoleRelation::getRoleId).collect(Collectors.toSet());
    }
}
